﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
using System.Threading;
using System.Drawing;

namespace WindowsFormsApplication1
{
    class PrivateController
    {
        
        [StructLayout(LayoutKind.Sequential)]
        public class KeyBoardHookStruct
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct MouseInput
        {
            public int dx;
            public int dy;
            public int mouseData;
            public int dwFlags;
            public int time;
            public IntPtr dwExtraInfo;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct KeyBoardInput
        {
            public short wVk;
            public short wScan;
            public int dwFlags;
            public int time;
            public IntPtr dwExtraInfo;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct HardwareInput
        {
            public int uMsg;
            public short wParamL;
            public short wParamH;
        }
        [StructLayout(LayoutKind.Explicit)]
        public struct Input
        {
            [FieldOffset(0)]
            public int type;
            [FieldOffset(4)]
            public MouseInput mouseInput;
            [FieldOffset(4)]
            public KeyBoardInput keyboardInput;
            [FieldOffset(4)]
            public HardwareInput hardwardInput;
        }
        #region DllImport
        [DllImport("User32.DLL", SetLastError = true)]
        public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
        [DllImport("User32.DLL", SetLastError=true)]
        public static extern int PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
        [DllImport("User32.DLL", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
        [DllImport("User32.dll", SetLastError = true)]
        public static extern uint SendInput(uint numberOfInputs, [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] Input[] input, int structSize);

        [DllImport("user32.dll")]
        public static extern IntPtr GetMessageExtraInfo();
        [DllImport("kernel32.dll")]
        public static extern int GetTickCount();
        [DllImport("user32.dll")]
        public static extern bool GetCursorPos(out Point pt);
        [DllImport("user32.dll")]
        public static extern bool SetCursorPos(Point pt);
        [DllImport("user32.dll")]
        public static extern int GetSystemMetrics(int nIndex);
        /*
        //设置钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        //抽掉钩子
        public static extern bool UnhookWindowsHookEx(int idHook);
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        //调用下一个钩子
        public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
        //取得模块句柄 
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);
         * */
        [DllImport("user32.dll")] 
        public static extern short GetKeyState(int nVirtKey); 
        #endregion


        public const uint WM_SETTEXT = 0x000C;
        public const uint WM_KEYDOWN = 0x0100;
        public const uint WM_KEYUP = 0x0101;
        public const uint WM_CHAR = 0x0102; 
        const uint WM_MOUSEMOVE = 0x0200;
        const uint WM_LBUTTONDOWN = 0x0201;
        const uint WM_LBUTTONUP = 0x0202;

        public IntPtr target = IntPtr.Zero;
        public List<IntPtr> targetList = new List<IntPtr>();

        /*
        public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
        private static int hHook = 0;
        private HookProc KeyBoardHookProcedure;
        private static int WH_KEYBOARD_LL = 13;

        public void Hook_Start()
        {
            // 安装键盘钩子
            if (hHook == 0)
            {
                KeyBoardHookProcedure = new HookProc(KeyBoardHookProc);

                hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyBoardHookProcedure, target, 0);

            }
        }
        public static int KeyBoardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if(nCode == 0) {
                KeyBoardHookStruct input = (KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyBoardHookStruct));
                if (input.vkCode == (int)VirtualKeys.VK_MENU)
                {
             
                }
            }
            return CallNextHookEx(hHook, nCode, wParam, lParam);
        }
         */

        public short GetVirtualKeyState(VirtualKeys vk) {
            return GetKeyState((int)vk);
        }

        public void setProcess(string ProcessName)
        {
            IntPtr tptr = IntPtr.Zero;
            targetList.Clear();
            while (true)
            {
                tptr = FindWindowEx(IntPtr.Zero, tptr, null, ProcessName);
                if (tptr == null || tptr == IntPtr.Zero || targetList.Contains(tptr))
                {
                    break;
                }
                targetList.Add(tptr);
            }
        }



        private static int MAKEPARAM(int l, int h)
        {
            return ((l & 0xffff) | (h << 0x10));
        }

        public void press(int keyCode)
        {
            if (target == null || target == IntPtr.Zero)
            {
                return;
            }
            int ret = PostMessage(target, WM_KEYDOWN, keyCode, 0);
            //ret = Marshal.GetLastWin32Error();
            PostMessage(target, WM_KEYUP, keyCode, 0);
        }

        public void mousedown(int x,int y)
        {
            if (target == null || target == IntPtr.Zero)
            {
                return;
            }
            int lparam = MAKEPARAM(x, y);
            //int ret = PostMessage(target, 0x0020, (int)target, MAKEPARAM(1, 0x0200));
            //PostMessage(target, 0x0084, 0, lparam);
            //PostMessage(target, WM_MOUSEMOVE, 0, lparam);
            Point p;
            GetCursorPos(out p);
            SetCursorPos(new Point(x, y));
            Thread.Sleep(10);
            int ret = SendMessage(target, WM_LBUTTONDOWN, 0x1, lparam);
            //Thread.Sleep(10);
            ret = SendMessage(target, WM_LBUTTONUP, 0, lparam);
            //Thread.Sleep(100);
            //Thread.Sleep(50);
            //SetCursorPos(p);
            
        }

        public void input(string str)
        {
            if (target == null || target == IntPtr.Zero)
            {
                return;
            }
            foreach (char c in str)
            {
                PostMessage(target, WM_CHAR, c, 0);
            }
        }



        public const int INPUT_MOUSE = 0;
        public const int INPUT_KEYBOARD = 1;
        public const int INPUT_HARDWARE = 2;
        public const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
        public const uint KEYEVENTF_KEYUP = 0x0002;
        public const uint KEYEVENTF_UNICODE = 0x0004;
        public const uint KEYEVENTF_SCANCODE = 0x0008;
        public const uint XBUTTON1 = 0x0001;
        public const uint XBUTTON2 = 0x0002;
        public const uint MOUSEEVENTF_MOVE = 0x0001;
        public const uint MOUSEEVENTF_LEFTDOWN = 0x0002;
        public const uint MOUSEEVENTF_LEFTUP = 0x0004;
        public const uint MOUSEEVENTF_RIGHTDOWN = 0x0008;
        public const uint MOUSEEVENTF_RIGHTUP = 0x0010;
        public const uint MOUSEEVENTF_MIDDLEDOWN = 0x0020;
        public const uint MOUSEEVENTF_MIDDLEUP = 0x0040;
        public const uint MOUSEEVENTF_XDOWN = 0x0080;
        public const uint MOUSEEVENTF_XUP = 0x0100;
        public const uint MOUSEEVENTF_WHEEL = 0x0800;
        public const uint MOUSEEVENTF_VIRTUALDESK = 0x4000;
        public const uint MOUSEEVENTF_ABSOLUTE = 0x8000;
    }
    public enum VirtualKeys : int
    {
            //VK_NUMLOCK = 0x90, //数字锁定键
            //VK_SCROLL = 0x91,  //滚动锁定
            //VK_CAPITAL = 0x14, //大小写锁定
            //VK_A = 62,         //键盘A
            VK_LBUTTON=1,      //鼠标左键
       　　 VK_RBUTTON=2,　    //鼠标右键
     　　　 VK_CANCEL=3,　　　 //Ctrl+Break(通常不需要处理)
　　　     VK_MBUTTON=4,　　  //鼠标中键
　　　      VK_BACK=8, 　　　  //Backspace
　　　      VK_TAB=9,　　　　  //Tab
　　　      VK_CLEAR=12,　　　 //Num Lock关闭时的数字键盘5
　　　      VK_RETURN=13,　　　//Enter(或者另一个)
　　      　VK_SHIFT=16,　　　 //Shift(或者另一个)
　　　      VK_CONTROL=17,　　 //Ctrl(或者另一个）
　　　      VK_MENU=18,　　　　//Alt(或者另一个)
　　　      VK_PAUSE=19,　　　 //Pause
　　　      VK_CAPITAL=20,　　 //Caps Lock
　　　      VK_ESCAPE=27,　　　//Esc
　　　      VK_SPACE=32,　　　 //Spacebar
　　　      VK_PRIOR=33,　　　 //Page Up
　　　      VK_NEXT=34,　　　　//Page Down
　　　      VK_END=35,　　　　 //End
　　　      VK_HOME=36,　　　　//Home
　　　      VK_LEFT=37,　　　  //左箭头
　　      　VK_UP=38,　　　　  //上箭头
　　　      VK_RIGHT=39,　　　 //右箭头
　　　      VK_DOWN=40,　　　  //下箭头
　　　      VK_SELECT=41,　　  //可选
　　　      VK_PRINT=42,　　　 //可选
　　　      VK_EXECUTE=43,　　 //可选
　　　      VK_SNAPSHOT=44,　　//Print Screen
　　　      VK_INSERT=45,　　　//Insert
　　　      VK_DELETE=46,　　  //Delete
　　　      VK_HELP=47,　　    //可选
            VK_NUM0=48,        //0
            VK_NUM1=49,        //1
            VK_NUM2=50,        //2
            VK_NUM3=51,        //3
            VK_NUM4=52,        //4
            VK_NUM5=53,        //5
            VK_NUM6=54,        //6
            VK_NUM7=55,        //7
            VK_NUM8=56,        //8
            VK_NUM9=57,        //9
            VK_A=65,           //A
            VK_B=66,           //B
            VK_C=67,           //C
            VK_D=68,           //D
            VK_E=69,           //E
            VK_F=70,           //F
            VK_G=71,           //G
            VK_H=72,           //H
            VK_I=73,           //I
            VK_J=74,           //J
            VK_K=75,           //K
            VK_L=76,           //L
            VK_M=77,           //M
            VK_N=78,           //N
            VK_O=79,           //O
            VK_P=80,           //P
            VK_Q=81,           //Q
            VK_R=82,           //R
            VK_S=83,           //S
            VK_T=84,           //T
            VK_U=85,           //U
            VK_V=86,           //V
            VK_W=87,           //W
            VK_X=88,           //X
            VK_Y=89,           //Y
            VK_Z=90,           //Z
            VK_NUMPAD0=96,     //0
            VK_NUMPAD1=97,     //1
            VK_NUMPAD2=98,     //2
            VK_NUMPAD3=99,     //3
            VK_NUMPAD4=100,    //4
            VK_NUMPAD5=101,    //5
            VK_NUMPAD6=102,    //6
            VK_NUMPAD7=103,    //7
            VK_NUMPAD8=104,    //8
            VK_NUMPAD9=105,    //9
　　        VK_NULTIPLY=106,　 //数字键盘上的*
　　　      VK_ADD=107,　　　　//数字键盘上的+
　　        VK_SEPARATOR=108,　//可选
　　        VK_SUBTRACT=109,　 //数字键盘上的-
　　        VK_DECIMAL=110,　　//数字键盘上的.
　　        VK_DIVIDE=111,　　 //数字键盘上的/
            VK_F1=112,
            VK_F2=113,
            VK_F3=114,
            VK_F4=115,
            VK_F5=116,
            VK_F6=117,
            VK_F7=118,
            VK_F8=119,
            VK_F9=120,
            VK_F10=121,
            VK_F11=122,
            VK_F12=123,
            VK_NUMLOCK=144,　　//Num Lock
　　        VK_SCROLL=145 　   // Scroll Lock
        }

}
